package cz.data.domain.market.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import cz.data.common.base.BaseResponse;
import cz.data.common.base.SimpleDataResponse;
import cz.data.common.base.TableDataResponse;
import cz.data.common.core.DataConstant;
import cz.data.common.core.JsonPage;
import cz.data.common.validate.ValidationGroups;
import cz.data.domain.market.mapstruct.TableApiMapper;
import cz.data.domain.market.model.MarketUtil;
import cz.data.domain.market.model.dto.TableApiDto;
import cz.data.domain.market.model.entity.TableApiEntity;
import cz.data.domain.market.model.query.TableApiQuery;
import cz.data.domain.market.model.vo.TableApiVo;
import cz.data.domain.market.service.TableApiService;
import cz.data.domain.metadata.model.entity.MetadataSourceEntity;
import cz.data.domain.metadata.model.entity.MetadataTableEntity;
import cz.data.domain.metadata.rpc.MetadataFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(tags = {"表接口API"})
@RestController
public class TableApiController {

    @Resource
    TableApiMapper tableApiMapper;
    @Resource
    TableApiService tableApiService;
    @Resource
    MetadataFeign metadataFeign;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "表接口-详情", notes = "根据url的id来获取详细信息")
    @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
    @GetMapping("/table/api/{id}")
    public SimpleDataResponse<TableApiVo> getTableApiById(@PathVariable String id) {
        TableApiEntity tableApiEntity = tableApiService.getTableApiById(id);
        return new SimpleDataResponse<>(tableApiMapper.toVO(tableApiEntity));
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "表接口-列表")
    @GetMapping("/table/api/list")
    public TableDataResponse<TableApiVo> getTableApiList() {
        QueryWrapper<TableApiEntity> queryWrapper = new QueryWrapper<>();
        List<TableApiEntity> list = tableApiService.list(queryWrapper);
        List<TableApiVo> collect = list.stream().map(tableApiMapper::toVO).collect(Collectors.toList());
        return new TableDataResponse<>(collect);
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "表接口-分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableApiQuery", value = "查询实体tableApiQuery", required = true, dataTypeClass = TableApiQuery.class)
    })
    @GetMapping("/table/api/page")
    public SimpleDataResponse<JsonPage<TableApiVo>> getTableApiPage(TableApiQuery tableApiQuery) {
        QueryWrapper<TableApiEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StringUtils.isNotBlank(tableApiQuery.getApiName()),
                TableApiEntity::getApiName, tableApiQuery.getApiName());
        queryWrapper.lambda().orderByDesc(TableApiEntity::getId);
        IPage<TableApiEntity> page = tableApiService.page(new Page<>(tableApiQuery.getPageNum(),
                tableApiQuery.getPageSize()), queryWrapper);
        List<TableApiVo> collect = page.getRecords().stream()
                .map(tableApiMapper::toVO)
                .peek(api -> {
                    api.setApiUrl(MarketUtil.appendPrefixPath(api.getApiUrl()));
                    MetadataSourceEntity source = metadataFeign.getMetadataSourceById(api.getSourceId());
                    if (Objects.nonNull(source)) {
                        api.setSourceId(source.getSourceName());
                    }
                    MetadataTableEntity table = metadataFeign.getMetadataTableById(api.getTableId());
                    if (Objects.nonNull(table)) {
                        api.setTableId(table.getTableName());
                    }
                })
                .collect(Collectors.toList());
        JsonPage<TableApiVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
        return new SimpleDataResponse<>(jsonPage);
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "表接口-新增")
    @ApiImplicitParam(name = "tableApi", value = "详细实体tableApi", required = true, dataType = "TableApiDto")
    @PostMapping("/table/api")
    public BaseResponse saveTableApi(@RequestBody @Validated({ValidationGroups.Insert.class}) TableApiDto tableApi) {
        return BaseResponse.withBoolean(tableApiService.saveTableApi(tableApi));
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "表接口-修改")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableApi", value = "详细实体tableApi", required = true, dataType = "TableApiDto")
    })
    @PutMapping("/table/api")
    public BaseResponse updateTableApi(@RequestBody @Validated({ValidationGroups.Update.class}) TableApiDto tableApi) {
        return BaseResponse.withBoolean(tableApiService.updateTableApi(tableApi));
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "表接口-删除", notes = "根据url的id来指定删除对象")
    @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
    @DeleteMapping("/table/api/{id}")
    public BaseResponse deleteTableApiById(@PathVariable String id) {
        return BaseResponse.withBoolean(tableApiService.deleteTableApi(Collections.singletonList(id)));
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "表接口-批量删除", notes = "根据url的ids来批量删除对象")
    @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path")
    @DeleteMapping("/table/api/batch/{ids}")
    public BaseResponse deleteTableApiBatch(@PathVariable List<String> ids) {
        return BaseResponse.withBoolean(tableApiService.deleteTableApi(ids));
    }

    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "表接口-发布")
    @ApiImplicitParam(name = "id", value = "表接口ID", required = true, dataType = "String", paramType = "path")
    @PutMapping("/table/api/release/{id}")
    public BaseResponse releaseTableApi(@PathVariable String id) {
        return BaseResponse.withBoolean(tableApiService.updateTableApiStatus(id, DataConstant.ApiState.RELEASE.getKey()));
    }

    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "表接口-取消发布")
    @ApiImplicitParam(name = "id", value = "表接口ID", required = true, dataType = "String", paramType = "path")
    @PutMapping("/table/api/release/{id}/cancel")
    public BaseResponse cancelReleaseTableApi(@PathVariable String id) {
        return BaseResponse.withBoolean(tableApiService.updateTableApiStatus(id, DataConstant.ApiState.CANCEL.getKey()));
    }
}
